package com.smedi.ismedi.inmail.core.port.adapter.persistence.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smedi.ismedi.inmail.core.application.command.AppVersionQuery;
import com.smedi.ismedi.inmail.core.domain.aggregatemodel.AppVersion;
import com.smedi.ismedi.inmail.core.domain.repository.AppVersionRepository;
import com.smedi.ismedi.inmail.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.model.AppVersionEntity;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.model.DingAttendanceResultEntity;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.mybatis.mapper.AppVersionMapper;
import com.smedi.ismedi.inmail.core.port.adapter.persistence.mybatis.mapper.DingAttendanceResultMapper;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @className: AppVersionRepositoryImpl
 * @Description: TODO
 * @version: v1.0.0
 * @author: wzx
 * @date: 2023/8/30 10:29
 */

@Repository
@AllArgsConstructor
public class AppVersionRepositoryImpl extends ServiceImpl<AppVersionMapper, AppVersionEntity> implements AppVersionRepository, IService<AppVersionEntity> {

    private final AdapterConverter adapterConverter;

    private final AppVersionMapper appVersionMapper;

    @Override
    public Long create(AppVersion appVersion) {
        AppVersionEntity appVersionEntity = adapterConverter.appVersionToAppVersionEntity(appVersion);
        appVersionMapper.insert(appVersionEntity);
        return appVersionEntity.getId();
    }

    @Override
    public Long update(AppVersion appVersion) {
        appVersionMapper.updateById(adapterConverter.appVersionToAppVersionEntity(appVersion));
        return appVersion.getId();
    }

    @Override
    public void remove(AppVersionQuery appVersionQuery) {
        appVersionMapper.delete(appVersionQueryToLambdaQueryWrapper(appVersionQuery));
    }

    @Override
    public AppVersion get(AppVersionQuery appVersionQuery) {
        LambdaQueryWrapper<AppVersionEntity> lambdaQueryWrapper = appVersionQueryToLambdaQueryWrapper(appVersionQuery);
        return adapterConverter.appVersionEntityToAppVersion(appVersionMapper.selectOne(lambdaQueryWrapper));
    }

    @Override
    public List<AppVersion> list(AppVersionQuery appVersionQuery) {
        LambdaQueryWrapper<AppVersionEntity> lambdaQueryWrapper = appVersionQueryToLambdaQueryWrapper(appVersionQuery);
        return adapterConverter.appVersionEntityToAppVersion(appVersionMapper.selectList(lambdaQueryWrapper));
    }

    @Override
    public Page<AppVersion> page(AppVersionQuery appVersionQuery) {
        LambdaQueryWrapper<AppVersionEntity> lambdaQueryWrapper = appVersionQueryToLambdaQueryWrapper(appVersionQuery);
        Page<AppVersionEntity> page = new Page<>(appVersionQuery.getCurrent(), appVersionQuery.getSize());
        Page<AppVersionEntity> page1 = appVersionMapper.selectPage(page, lambdaQueryWrapper);
        return adapterConverter.appVersionEntityToAppVersion(appVersionMapper.selectPage(page, lambdaQueryWrapper));
    }

    private LambdaQueryWrapper<AppVersionEntity> appVersionQueryToLambdaQueryWrapper(AppVersionQuery appVersionQuery) {
        LambdaQueryWrapper<AppVersionEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.eq(appVersionQuery.getId() != null, AppVersionEntity::getId, appVersionQuery.getId());
        lambdaQueryWrapper.eq(StringUtils.isNotBlank(appVersionQuery.getSystemType()), AppVersionEntity::getSystemType, appVersionQuery.getSystemType());
        lambdaQueryWrapper.ne(appVersionQuery.getIdNe() != null, AppVersionEntity::getId, appVersionQuery.getIdNe());
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(appVersionQuery.getIds()), AppVersionEntity::getId, appVersionQuery.getIds());
        lambdaQueryWrapper.eq(appVersionQuery.getEnable() != null, AppVersionEntity::getEnable, appVersionQuery.getEnable());
        lambdaQueryWrapper.eq(StringUtils.isNotBlank(appVersionQuery.getMethod()), AppVersionEntity::getMethod, appVersionQuery.getMethod());

        if (StringUtils.isNotBlank(appVersionQuery.getAppVersion()) && appVersionQuery.getAppVersion().matches("^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$")) {
            String[] versions = StringUtils.split(appVersionQuery.getAppVersion(), ".");
            lambdaQueryWrapper.eq(AppVersionEntity::getVersionOne, versions[0]);
            lambdaQueryWrapper.eq(AppVersionEntity::getVersionTwo, versions[1]);
            lambdaQueryWrapper.eq(AppVersionEntity::getVersionThree, versions[2]);
        }

        if (StringUtils.isNotBlank(appVersionQuery.getVersionGt())) {
            String[] versions = StringUtils.split(appVersionQuery.getVersionGt(), ".");
            lambdaQueryWrapper.and(lambdaQueryWrapper1 -> {
                lambdaQueryWrapper1.gt(AppVersionEntity::getVersionOne, versions[0]);
                lambdaQueryWrapper1.or(lambdaQueryWrapper2 ->
                        lambdaQueryWrapper2.eq(AppVersionEntity::getVersionOne, versions[0])
                                .gt(AppVersionEntity::getVersionTwo, versions[1]));
                lambdaQueryWrapper1.or(lambdaQueryWrapper3 ->
                        lambdaQueryWrapper3.eq(AppVersionEntity::getVersionOne, versions[0])
                                .eq(AppVersionEntity::getVersionTwo, versions[1])
                                .gt(AppVersionEntity::getVersionThree, versions[2]));
            });
        }

        if (StringUtils.isNotBlank(appVersionQuery.getOrderBy())) {
            if (StringUtils.isBlank(appVersionQuery.getAsc())) {
                appVersionQuery.setAsc("desc");
            }
            if(appVersionQuery.getOrderBy().equals("appVersion")){
                lambdaQueryWrapper.orderBy(true,appVersionQuery.getAsc().equals("asc"),AppVersionEntity::getVersionOne, AppVersionEntity::getVersionTwo, AppVersionEntity::getVersionThree);
            }else {
                lambdaQueryWrapper.last("order by " + camelToUnderline(appVersionQuery.getOrderBy()) + " " + appVersionQuery.getAsc());
            }
        }
        return lambdaQueryWrapper;
    }

    private String camelToUnderline(String str) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append("_").append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}